package common

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"

	"github.com/ethereum/go-ethereum/accounts/keystore"
)

// 支持多种以太坊链，如ETH, BSC等
type ChainInfo struct {
	ChainId      int      `json:"chainId"`      // 链id mainnet:1 ropsten:3 bsc:56 bsc testnet:97 等等
	NodePath     string   `json:"nodePath"`     // 访问该链地址，可以是本地建立节点后提供的访问地址，也可使用第三方提供访问地址如infura.io
	NodeWssPath  string   `json:"nodeWssPath"`  // wss地址，用于接收合约事件通知
	WatchAddress []string `json:"watchAddress"` // wss接收具体合约上（可多个合约）事件通知
}

type NftConf struct {
	RunEnv         string               `json:"runEnv,omitempty"` // 当前运行环境 test: 测试 prod: 正式环境
	ServerAddr     string               `json:"serverAddr"`       // 服务监听ip端口
	LogLevel       int                  `json:"logLevel"`         // 日志级别
	SignRandomKey  string               `json:"signRandomKey"`    // http访问加密串
	SecretWord     string               `json:"secretWord"`       // 本地钱包密码（重要，请勿泄露！）
	WalletPath     string               `json:"walletPath"`       // 本地钱包保存路径
	SupportChains  map[string]ChainInfo `json:"supportChains"`    // 合约支持链信息
	NotifyHttpPath string               `json:"notifyHttpPath"`   // 合约事件通知（如未配置则不通知）
	IpfsNodePath   string               `json:"ipfsNodePath"`     // NFT实际内容上传到ipfs的访问路径（如未配置则不上传）
	LocalWallet    *keystore.KeyStore   `json:"-"`                // 本地钱包中所有账户
}

var GlobalConf NftConf

func LoadConfig(file string) error {
	buf, err := ioutil.ReadFile(file)
	if err != nil {
		fmt.Println("Read config file failed!")
		return err
	}
	err = json.Unmarshal(buf, &GlobalConf)
	if err != nil {
		fmt.Println("Decode config file failed!")
		return err
	}
	// 加载钱包中账户
	if len(GlobalConf.WalletPath) <= 0 {
		return errors.New("Not set wallet path!")
	}
	GlobalConf.LocalWallet = keystore.NewKeyStore(GlobalConf.WalletPath, keystore.StandardScryptN, keystore.StandardScryptP)
	// 重置配置文件中钱包密码信息，防止密码泄露！
	if GlobalConf.RunEnv == "prod" {
		tmpConf := GlobalConf
		tmpConf.SecretWord = ""
		buf, err = json.Marshal(tmpConf)
		err = ioutil.WriteFile(file, buf, 0600)
		if err != nil {
			fmt.Println("Rewrite config file failed!")
		}
	}
	return nil
}
